package com.sk.openapicallexample_android.http.interceptor;


import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sk.openapicallexample_android.common.CommonUtil;
import com.sk.openapicallexample_android.http.RetrofitFactory;
import com.sk.openapicallexample_android.http.bean.normalbean.BaseEntity;
import com.sk.openapicallexample_android.http.config.HttpConfig;
import com.sk.openapicallexample_android.http.sign.SignUtil;

import java.io.IOException;
import java.nio.charset.Charset;


import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import okio.BufferedSource;


/**
 * Created by yemao on 2017/3/23.
 */

public class InterceptorUtil {
    private static String TAG = "InterceptorUtil";
    //签名头的key
    private static String X_CA_SIFNATURE_KEY = "X-Ca-Signature";
    public final static Charset UTF8 = Charset.forName("UTF-8");
    private static String TOKEN_KEY = "token";


    public static HttpLoggingInterceptor getLogInterceptor() {
        return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.e(TAG, message + "");
            }
        }).setLevel(HttpLoggingInterceptor.Level.BODY);
    }

    /****
     * 设置请求头的Interceptor
     *
     * @return
     * @throws Exception
     */
    public static Interceptor getHeaderInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {


                String token = null;

                if (token == null) {
                    //模拟token不为空时

                    //当token为空时去获取token
                    token = refreshToken(chain) + "";
                    Request request = chain.request();
                    request = request.newBuilder()
                            .removeHeader(TOKEN_KEY)
                            .addHeader(TOKEN_KEY, token.trim().toString())
                            .build();
                    request = buildRequestToAddHeads(request);

                    return chain.proceed(request);
                } else {//模拟token为空时


                    Request request = buildRequestToAddHeads(chain.request());
                    Response response = chain.proceed(request);

                    //token失效重新获取token
                    if (response.code() == 401) {

                        //当token为空时去获取token
                        token = refreshToken(chain) + "";
                        request = chain.request();
                        request = request.newBuilder()
                                .removeHeader(TOKEN_KEY)
                                .addHeader(TOKEN_KEY, token.trim().toString())
                                .build();
                        request = buildRequestToAddHeads(request);

                        return chain.proceed(request);

                    } else {
                        return response;
                    }

                }

            }
        };
    }


    /**
     * 获取token
     *
     * @param chain
     * @return
     * @throws Exception
     */
    private static String refreshToken(Interceptor.Chain chain) throws IOException {

        //经过特殊处理的授权接口
        retrofit2.Call<String> mCall = RetrofitFactory.getInstence().API().authorization1(HttpConfig.UUID);
        Request request = buildRequestToAddHeads(mCall.request());
        Response response = chain.proceed(request);
        //得到响应体
        ResponseBody responseBody = response.body();

        //得到缓冲源
        BufferedSource source = responseBody.source();

        //请求全部
        source.request(Long.MAX_VALUE); // Buffer the entire body.
        Buffer buffer = source.buffer();
        Charset charset = UTF8;

        MediaType contentType = responseBody.contentType();

        if (contentType != null) {
            charset = contentType.charset(UTF8);
        }
        //读取返回数据
        String bodyString = buffer.clone().readString(charset);

        //解析返回数据
        BaseEntity<String> mBaseEntity = null;
        try {
            if (bodyString != null) {
                Gson gson = new Gson();
                mBaseEntity = gson.fromJson(bodyString, new TypeToken<BaseEntity<String>>() {
                }.getType());
            }
        } catch (Exception e) {
            e.printStackTrace();

        }

        return mBaseEntity == null ? null : mBaseEntity.getData();
    }

    /***
     * 设置请求的headers
     * @param oldrequest
     * @return
     */
    public static Request buildRequestToAddHeads(Request oldrequest) {
        long mTimestamp = System.currentTimeMillis();
        Request request = oldrequest.newBuilder()
                .addHeader("Host", )//需填入自己的host 例如：apis.80ct.com
                .addHeader("Date", CommonUtil.dateFormat(mTimestamp))
                .addHeader("User-Agent", "Apache-HttpClient/4.1.2 (java 1.6)")
                .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")////请求体类型，请根据实际请求体内容设置。
                .addHeader("Accept", "application/json")////请求响应体类型，部分 API 可以根据指定的响应类型来返回对应数据格式，建议手动指定此请求头，如果不设置，部分 HTTP 客户端会设置默认值 */*，导致签名错误。
                .addHeader("X-Ca-Request-Mode", "debug")////是否开启 Debug 模式，大小写不敏感，不设置默认关闭，一般 API 调试阶段可以打开此设置。
                .addHeader("X-Ca-Version", "1")//API版本号，为日期形式：YYYY-MM-DD，本版本对应为2016-07-14
                .addHeader("X-Ca-Signature-Headers", "X-Ca-Request-Mode,X-Ca-Version,X-Ca-Stage,X-Ca-Key,X-Ca-Timestamp")////参与签名的自定义请求头，服务端将根据此配置读取请求头进行签名，此处设置不包含 Content-Type、Accept、Content-MD5、Date 请求头，这些请求头已经包含在了基础的签名结构中，详情参照请求签名说明文档。
                .addHeader("X-Ca-Stage", "RELEASE")////请求 API的Stage，目前支持 TEST、PRE、RELEASE 三个 Stage，大小写不敏感，API 提供者可以选择发布到哪个 Stage，只有发布到指定 Stage 后 API 才可以调用，否则会提示 API 找不到或 Invalid Url。
                .addHeader("X-Ca-Key", HttpConfig.APPKEY)////请求的 AppKey，请到 API 网关控制台生成，只有获得 API 授权后才可以调用，通过云市场等渠道购买的 API 默认已经给APP授过权，阿里云所有云产品共用一套 AppKey 体系，删除 ApppKey 请谨慎，避免影响到其他已经开通服务的云产品。
                .addHeader("X-Ca-Timestamp", mTimestamp + "")
                .addHeader("X-Ca-Nonce", CommonUtil.getRandom() + "")////请求唯一标识，15分钟内 AppKey+API+Nonce 不能重复，与时间戳结合使用才能起到防重放作用。
                .build();
//        String stringToSign = SignUtil.buildStringToSign(request);
//        String xx=stringToSign.replace("\n","#");
//        Log.e(TAG, "intercept:stringToSign "+stringToSign );
//        Log.e(TAG, "intercept:xx "+xx );

        //进行签名
        String clientSign = SignUtil.getSign(request);
        Log.e(TAG, "intercept clientSign: " + clientSign);

        request = request.newBuilder()
                .addHeader(X_CA_SIFNATURE_KEY, clientSign)
                .build();
        return request;
    }


}
